package qidi.gushi;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.iflytek.speech.setting.IatSettings;
import com.iflytek.speech.setting.TtsSettings;
import com.iflytek.speech.util.JsonParser;
import com.iflytek.sunflower.FlowerCollector;
import com.iflytek.voicedemo.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.LinkedHashMap;
/**主界面*/
public class MainActivity extends BaseActivity
{
    /**界面创建后*/
    @SuppressLint("ShowToast")
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        initView();
    }
    /**初始化界面控件*/
    public void initView(){
        setContentView(R.layout.activity_main);
        ting=(Button)findViewById(R.id.ting);
        du=(Button)findViewById(R.id.du);
        bei=(Button)findViewById(R.id.bei);
        mohu=(ImageView)findViewById(R.id.mohu);
        mohu.setVisibility(View.GONE);
        zi =(ImageView)findViewById(R.id.zi);
        root=(LinearLayout)findViewById(R.id.root);
        tts_text=(TextView)findViewById(R.id.tts_text);
        lustatu=(TextView)findViewById(R.id.lustatu);
        lustatu2=(TextView)findViewById(R.id.lustatu2);
        tishi=(Button)findViewById(R.id.tishi);
        tishi.setVisibility(View.GONE);
        shiting=(Button)findViewById(R.id.shiting);
        tijiao=(Button)findViewById(R.id.tijiao);
        rec=(Button)findViewById(R.id.rec);
        gv_shi = (GridView)findViewById(R.id.gv_shi);
        initData();
    }
    /**初始化数据*/
    public void initData(){
        // 初始化合成对象
        mTts=SpeechSynthesizer.createSynthesizer(MainActivity.this,mTtsInitListener);
        // 云端发音人名称列表
        mCloudVoicersEntries=getResources().getStringArray(R.array.voicer_cloud_entries);
        mCloudVoicersValue=getResources().getStringArray(R.array.voicer_cloud_values);
        mSharedPreferences=getSharedPreferences(TtsSettings.PREFER_NAME,MODE_PRIVATE);
        mToast=Toast.makeText(this,"",Toast.LENGTH_SHORT);
        // 初始化识别无UI识别对象
        // 使用SpeechRecognizer对象，可根据回调消息自定义界面；
        mIat=SpeechRecognizer.createRecognizer(MainActivity.this,mInitListener);
        // 初始化听写Dialog，如果只使用有UI听写功能，无需创建SpeechRecognizer
        // 使用UI听写功能，请根据sdk文件目录下的notice.txt,放置布局文件和图片资源
        mIatDialog=new RecognizerDialog(MainActivity.this,mInitListener);
        mSharedPreferencesDu=getSharedPreferences(IatSettings.PREFER_NAME,Activity.MODE_PRIVATE);
        mToast=Toast.makeText(this,"",Toast.LENGTH_SHORT);
        //ting.setOnClickListener(this);
        adapter = new GuShiAdapter(this);
        gv_shi.setAdapter(adapter);
        ShiItemChick shiItemChick = new ShiItemChick();
        gv_shi.setOnItemClickListener(shiItemChick);
        context = this;
    }
    /**设置语音参数*/
    private void setParam()
    {
        // 清空参数
        mTts.setParameter(SpeechConstant.PARAMS,null);
        // 根据合成引擎设置相应参数
        if(mEngineType.equals(SpeechConstant.TYPE_CLOUD))
        {
            mTts.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_CLOUD);
            // 设置在线合成发音人
            mTts.setParameter(SpeechConstant.VOICE_NAME,voicer);
            //设置合成语速
            mTts.setParameter(SpeechConstant.SPEED,mSharedPreferences.getString("speed_preference","50"));
            //设置合成音调
            mTts.setParameter(SpeechConstant.PITCH,mSharedPreferences.getString("pitch_preference","50"));
            //设置合成音量
            mTts.setParameter(SpeechConstant.VOLUME,mSharedPreferences.getString("volume_preference","50"));
        }else
        {
            mTts.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);
            // 设置本地合成发音人 voicer为空，默认通过语记界面指定发音人。
            mTts.setParameter(SpeechConstant.VOICE_NAME,"");
            //            *
            //             * TODO 本地合成不设置语速、音调、音量，默认使用语记设置
            //             * 开发者如需自定义参数，请参考在线合成参数设置
        }
        //设置播放器音频流类型
        mTts.setParameter(SpeechConstant.STREAM_TYPE,mSharedPreferences.getString("stream_preference","3"));
        // 设置播放合成音频打断音乐播放，默认为true
        mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS,"true");
        // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注：AUDIO_FORMAT参数语记需要更新版本才能生效
        mTts.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
        mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,Environment.getExternalStorageDirectory()+"/msc/tts.wav");
    }
    /**听*/
    public void ting(View view)
    {
        LogUtils.e("听");
        select="听";
        mohu.setVisibility(View.GONE);
        ting.setWidth(180);
        ting.setHeight(180);
        du.setWidth(120);
        du.setHeight(120);
        bei.setWidth(120);
        bei.setHeight(120);
        tishi.setVisibility(View.GONE);

        lustatu.setText("录音已停止");
        lustatu2.setText("重新录音...");
        rec.setEnabled(false);

        if(null==mTts)
        {
            // 创建单例失败，与 21001 错误为同样原因，参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
            this.showTip("创建对象失败，请确认 libmsc.so 放置正确，且有调用 createUtility 进行初始化");
            return;
        }
        // 移动数据分析，收集开始合成事件
        FlowerCollector.onEvent(MainActivity.this,"tts_play");
        String text=((TextView)findViewById(R.id.tts_text)).getText().toString();
        // 设置参数
        setParam();
        int code=mTts.startSpeaking(text,mTtsListener);
        //			*
        //			 * 只保存音频不进行播放接口,调用此接口请注释startSpeaking接口
        //			 * text:要合成的文本，uri:需要保存的音频全路径，listener:回调接口
        //
        //			String path = Environment.getExternalStorageDirectory()+"/tts.ico";
        //			int code = mTts.synthesizeToUri(text, path, mTtsListener);
        if(code!=ErrorCode.SUCCESS)
        {
            showTip("语音合成失败,错误码: "+code);
        }
    }
    /**显示提示*/
    private void showTip(final String str)
    {
        mToast.setText(str);
        mToast.show();
    }
    /**录音*/
    public void rec(View v)
    {
        LogUtils.e("点击录音图标");
        String text=lustatu.getText().toString();
        if(select.equals("背"))
        {
            if(text.contains("录音中"))
            {
                rec.setBackgroundResource(R.drawable.rec);
                lustatu.setText("录音已暂停，点击录音按钮继续背诵");
                lustatu2.setText("继续背诵...");
            }else if(text.contains("已暂停")||text.contains("未开始"))
            {
                rec.setBackgroundResource(R.drawable.stop);
                lustatu.setText("正在录音中");
                lustatu2.setText("完成录音");
            }
        }else if(select.equals("读")||select.equals("听"))
        {
            if(text.contains("录音中"))
            {
                rec.setBackgroundResource(R.drawable.rec);
                lustatu.setText("录音已停止");
                lustatu2.setText("重新录音...");
                LuYin.stopVioce();
            }else if(text.contains("已停止")||text.contains("未开始"))
            {
                rec.setBackgroundResource(R.drawable.stop);
                lustatu.setText("正在录音中");
                lustatu2.setText("完成录音");
                LuYin.startVoice();
            }
        }
    }
    /**试听*/
    public void shiting(View v)
    {
        LogUtils.e("试听");
        String text=shiting.getText().toString();
        if(text.contains("作品"))
        {
            LuYin.playVoice();
            shiting.setText("停止试听");
        }else if(text.contains("停止"))
        {
            LuYin.stopPlayVoice();
            shiting.setText("试听作品");
        }
    }
    public void tijiao(View v)
    {
        LogUtils.e("提交");
    }
    /**背*/
    public void bei(View view)
    {
        LogUtils.e("背");
        mohu.setVisibility(View.VISIBLE);
        //放大这个圆圈，缩放其他按钮。
        //60dp
        bei.setWidth(180);
        bei.setHeight(180);
        bei.requestLayout();
        bei.refreshDrawableState();
        bei.invalidate();
        du.setWidth(120);
        du.setHeight(120);
        ting.setWidth(120);
        ting.setHeight(120);
        tishi.setVisibility(View.VISIBLE);
        rec.setEnabled(true);
        String text=lustatu.getText().toString();
        if(text.contains("录音中")||text.contains("已停止"))
        {
            rec.setBackgroundResource(R.drawable.rec);
            lustatu.setText("录音已暂停，点击录音按钮继续背诵");
            lustatu2.setText("继续背诵...");

        }else if(text.contains("已暂停")||text.contains("未开始"))
        {
            rec.setBackgroundResource(R.drawable.stop);
            lustatu.setText("正在录音中");
            lustatu2.setText("完成录音");
        }
        select="背";
        //        final Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.zi);
        //        final Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.bj);
        //        final Bitmap bitmap = Bitmap.createBitmap(getScreenShot(),200,200,200,200);
        //        final Bitmap bitmap = getScreenShot(root);
        //                final Bitmap bitmap = getScreenShot(tts_text);  //全屏的..
        //        final Bitmap bitmap = loadBitmapFromView(tts_text);
        //        final Bitmap bitmap =loadBitmapFromViewBySystem(tts_text);
//        final Bitmap bitmap=Bitmap.createBitmap(getScreenShot(root),212,155,300,280);
//        Bitmap finalBitmap=Fuzzy_Background.with(MainActivity.this).bitmap(bitmap) //要模糊的图片
//                .radius(3)//模糊半径  单个字3还是不错的
//                .blur();
        //                mohu.setImageBitmap(finalBitmap);
//        mohu.setBackground(new BitmapDrawable(finalBitmap));
        //        root.setBackground(new BitmapDrawable(finalBitmap));
        //        zi.setBackground(new BitmapDrawable(finalBitmap));
    }
    public static Bitmap loadBitmapFromViewBySystem(View v)
    {
        if(v==null)
        {
            return null;
        }
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache();
        Bitmap bitmap=v.getDrawingCache();
        return bitmap;
    }
    public static Bitmap loadBitmapFromView(View v)
    {
        if(v==null)
        {
            return null;
        }
        Bitmap screenshot;
        screenshot=Bitmap.createBitmap(v.getWidth(),v.getHeight(),Bitmap.Config.ARGB_4444);
        Canvas canvas=new Canvas(screenshot);
        canvas.translate(-v.getScrollX(),-v.getScrollY());//我们在用滑动View获得它的Bitmap时候，获得的是整个View的区域（包括隐藏的），如果想得到当前区域，需要重新定位到当前可显示的区域
        v.draw(canvas);// 将 view 画到画布上
        return screenshot;
    }
    /**
     调用系统截图功能获取屏幕截图
     @return
     */
    private Bitmap getScreenShot(View view)
    {
        view=getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        return view.getDrawingCache();
    }
    /**读*/
    public void du(View view)
    {
        LogUtils.e("读");
        select="读";
        mohu.setVisibility(View.GONE);
        du.setWidth(180);
        du.setHeight(180);
        bei.setWidth(120);
        bei.setHeight(120);
        ting.setWidth(120);
        ting.setHeight(120);
        tishi.setVisibility(View.GONE);
        rec.setEnabled(true);
        String text=lustatu.getText().toString();
        if(text.contains("录音中"))
        {
            rec.setBackgroundResource(R.drawable.rec);
            lustatu.setText("录音已停止");
            lustatu2.setText("重新录音...");
        }else if(text.contains("已停止")||text.contains("未开始")||text.contains("已暂停"))
        {
            rec.setBackgroundResource(R.drawable.stop);
            lustatu.setText("正在录音中");
            lustatu2.setText("完成录音");
        }
        if(null==mIat)
        {
            // 创建单例失败，与 21001 错误为同样原因，参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
            this.showTip("创建对象失败，请确认 libmsc.so 放置正确，且有调用 createUtility 进行初始化");
            return;
        }
        // 开始听写
        // 如何判断一次听写结束：OnResult isLast=true 或者 onError
        // 移动数据分析，收集开始听写事件
        FlowerCollector.onEvent(MainActivity.this,"iat_recognize");
        //        mResultText.setText(null);// 清空显示内容
        mIatResults.clear();
        // 设置参数
        setParam();
        boolean isShowDialog=mSharedPreferencesDu.getBoolean(getString(R.string.pref_key_iat_show),true);
        if(isShowDialog)
        {
            // 显示听写对话框
            mIatDialog.setListener(mRecognizerDialogListener);
            mIatDialog.show();
            showTip(getString(R.string.text_begin));
        }else
        {
            // 不显示听写对话框
            ret=mIat.startListening(mRecognizerListener);
            if(ret!=ErrorCode.SUCCESS)
            {
                showTip("听写失败,错误码："+ret);
            }else
            {
                showTip(getString(R.string.text_begin));
            }
        }
    }
    /**打印结果*/
    private void printResult(RecognizerResult results)
    {
        String text=JsonParser.parseIatResult(results.getResultString());
        String sn=null;
        // 读取json结果中的sn字段
        try
        {
            JSONObject resultJson=new JSONObject(results.getResultString());
            sn=resultJson.optString("sn");
        }catch(JSONException e)
        {
            e.printStackTrace();
        }
        mIatResults.put(sn,text);
        StringBuffer resultBuffer=new StringBuffer();
        for(String key : mIatResults.keySet())
        {
            resultBuffer.append(mIatResults.get(key));
        }
        //        mResultText.setText(resultBuffer.toString());
        //        mResultText.setSelection(mResultText.length());
        LogUtils.e("识别结果："+resultBuffer.toString());
        showTip("识别结果："+resultBuffer.toString());
    }
    /**古诗的网格布局控件*/
    GridView gv_shi;
    /**模糊*/
    ImageView mohu;
    /**字*/
    ImageView zi;
    /**读 按钮*/
    Button du;
    /**听 按钮*/
    Button ting;
    /**背 按钮*/
    Button bei;
    /**提示 按钮*/
    Button tishi;
    /**试听 按钮*/
    static Button shiting;
    /**提交 按钮*/
    Button tijiao;
    /**录音 按钮*/
    Button rec;
    /**根布局*/
    LinearLayout root;
    /**语音识别文本控件*/
    TextView tts_text;
    /**录音状态*/
    TextView lustatu;
    /**录音状态 第2个*/
    TextView lustatu2;
    /**选择的*/
    String select="";
    /**古诗网格适配器*/
    BaseAdapter adapter;
    /**环境*/
    static Context context;
    // 语音听写对象
    private SpeechRecognizer mIat;
    // 语音听写UI
    private RecognizerDialog mIatDialog;
    // 用HashMap存储听写结果
    private HashMap<String,String> mIatResults=new LinkedHashMap<String,String>();
    /***/
    int ret=0; // 函数调用返回值
    /***/
    private boolean mTranslateEnable=false;
    /***/
    private SharedPreferences mSharedPreferencesDu;
    /***/
    private static String TAG=MainActivity.class.getSimpleName();
    // 语音合成对象
    private SpeechSynthesizer mTts;
    // 默认发音人
    private String voicer="xiaoyan";
    /***/
    private String[] mCloudVoicersEntries;
    /***/
    private String[] mCloudVoicersValue;
    // 缓冲进度
    private int mPercentForBuffering=0;
    // 播放进度
    private int mPercentForPlaying=0;
    // 云端/本地单选按钮
    private RadioGroup mRadioGroup;
    // 引擎类型
    private String mEngineType=SpeechConstant.TYPE_CLOUD;
    /***/
    private Toast mToast;
    /***/
    private SharedPreferences mSharedPreferences;
    /**
     听写监听器。
     */
    private RecognizerListener mRecognizerListener=new RecognizerListener()
    {
        @Override
        public void onBeginOfSpeech()
        {
            // 此回调表示：sdk内部录音机已经准备好了，用户可以开始语音输入
            showTip("开始说话");
        }
        @Override
        public void onError(SpeechError error)
        {
            // Tips：
            // 错误码：10118(您没有说话)，可能是录音机权限被禁，需要提示用户打开应用的录音权限。
            // 如果使用本地功能（语记）需要提示用户开启语记的录音权限。
            if(mTranslateEnable&&error.getErrorCode()==14002)
            {
                showTip(error.getPlainDescription(true)+"\n请确认是否已开通翻译功能");
            }else
            {
                showTip(error.getPlainDescription(true));
            }
        }
        @Override
        public void onEndOfSpeech()
        {
            // 此回调表示：检测到了语音的尾端点，已经进入识别过程，不再接受语音输入
            showTip("结束说话");
        }
        private void printTransResult(RecognizerResult results)
        {
            String trans=JsonParser.parseTransResult(results.getResultString(),"dst");
            String oris=JsonParser.parseTransResult(results.getResultString(),"src");
            if(TextUtils.isEmpty(trans)||TextUtils.isEmpty(oris))
            {
                showTip("解析结果失败，请确认是否已开通翻译功能。");
            }else
            {
                //                mResultText.setText( "原始语言:\n"+oris+"\n目标语言:\n"+trans );
            }
        }
        @Override
        public void onResult(RecognizerResult results,boolean isLast)
        {
            Log.d(TAG,results.getResultString());
            if(mTranslateEnable)
            {
                printTransResult(results);
            }else
            {
                printResult(results);
            }
            if(isLast)
            {
                // TODO 最后的结果
            }
        }
        @Override
        public void onVolumeChanged(int volume,byte[] data)
        {
            showTip("当前正在说话，音量大小："+volume);
            Log.d(TAG,"返回音频数据："+data.length);
        }
        @Override
        public void onEvent(int eventType,int arg1,int arg2,Bundle obj)
        {
            // 以下代码用于获取与云端的会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            // 若使用本地能力，会话id为null
            //	if (SpeechEvent.EVENT_SESSION_ID == eventType) {
            //		String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
            //		Log.d(TAG, "session id =" + sid);
            //	}
        }
    };
    /**
     听写UI监听器
     */
    private RecognizerDialogListener mRecognizerDialogListener=new RecognizerDialogListener()
    {
        public void onResult(RecognizerResult results,boolean isLast)
        {
            if(mTranslateEnable)
            {
                //                printTransResult( results );
            }else
            {
                printResult(results);
            }
        }
        /**
         * 识别回调错误.
         */
        public void onError(SpeechError error)
        {
            if(mTranslateEnable&&error.getErrorCode()==14002)
            {
                showTip(error.getPlainDescription(true)+"\n请确认是否已开通翻译功能");
            }else
            {
                showTip(error.getPlainDescription(true));
            }
        }
    };
    /**
     合成回调监听。
     */
    private SynthesizerListener mTtsListener=new SynthesizerListener()
    {
        @Override
        public void onSpeakBegin()
        {
            showTip("开始播放");
        }
        @Override
        public void onSpeakPaused()
        {
            showTip("暂停播放");
        }
        @Override
        public void onSpeakResumed()
        {
            showTip("继续播放");
        }
        @Override
        public void onBufferProgress(int percent,int beginPos,int endPos,String info)
        {
            // 合成进度
            mPercentForBuffering=percent;
            showTip(String.format(getString(R.string.tts_toast_format),mPercentForBuffering,mPercentForPlaying));
        }
        @Override
        public void onSpeakProgress(int percent,int beginPos,int endPos)
        {
            // 播放进度
            mPercentForPlaying=percent;
            showTip(String.format(getString(R.string.tts_toast_format),mPercentForBuffering,mPercentForPlaying));
        }
        @Override
        public void onCompleted(SpeechError error)
        {
            if(error==null)
            {
                showTip("播放完成");
            }else if(error!=null)
            {
                showTip(error.getPlainDescription(true));
            }
        }
        @Override
        public void onEvent(int eventType,int arg1,int arg2,Bundle obj)
        {
            // 以下代码用于获取与云端的会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            // 若使用本地能力，会话id为null
            //	if (SpeechEvent.EVENT_SESSION_ID == eventType) {
            //		String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
            //		Log.d(TAG, "session id =" + sid);
            //	}
        }
    };
    /**
     初始化监听。
     */
    private InitListener mTtsInitListener=new InitListener()
    {
        @Override
        public void onInit(int code)
        {
            Log.d(TAG,"InitListener init() code = "+code);
            if(code!=ErrorCode.SUCCESS)
            {
                showTip("初始化失败,错误码："+code);
            }else
            {
                // 初始化成功，之后可以调用startSpeaking方法
                // 注：有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成，
                // 正确的做法是将onCreate中的startSpeaking调用移至这里
            }
        }
    };
    /**
     初始化监听器。
     */
    private InitListener mInitListener=new InitListener()
    {
        @Override
        public void onInit(int code)
        {
            Log.d(TAG,"SpeechRecognizer init() code = "+code);
            if(code!=ErrorCode.SUCCESS)
            {
                showTip("初始化失败，错误码："+code);
            }
        }
    };
    /**显示字的解释*/
    public static void showZiJieShi(String zi)
    {
        //这里采用对话框的方式显示出来。然后带有关闭按钮 或者采用页面的方式展示出来。
        ZiJieShi.openSelf(context,zi);
    }
}
